import csv
import json
import math
import random

import matplotlib.colors as mcolors
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
colors = list(dict(mcolors.BASE_COLORS, **mcolors.CSS4_COLORS).keys())


car_points = [{"car_id": 1,
               "start_point": {
                   "longitude": 105.71892594481322,
                   "latitude": 38.854270759487839
               },
               "pass_points": [
                   {
                       "longitude": 105.71888429971857,
                       "latitude": 38.855208398083782
                   },
                   {
                       "longitude": 105.71371699892107,
                       "latitude": 38.8696918981644
                   }
               ]},
              {"car_id": 2,
               "start_point": {
                   "longitude": 105.71892594481322,
                   "latitude": 38.854270759487839
               },
               "pass_points": [
                   {
                       "longitude": 105.71888429971857,
                       "latitude": 38.855208398083782
                   },
                   {
                       "longitude": 105.718804399254,
                       "latitude": 38.856252600646904
                   },
                   {
                       "longitude": 105.71873950109577,
                       "latitude": 38.857100998154841
                   },
                   {
                       "longitude": 105.7186005987614,
                       "latitude": 38.858820799709768
                   },
                   {
                       "longitude": 105.71845210114108,
                       "latitude": 38.860722401698133
                   },
                   {
                       "longitude": 105.71832589887211,
                       "latitude": 38.861902098710246
                   },
                   {
                       "longitude": 105.71831730128878,
                       "latitude": 38.862000999988616
                   },
                   {
                       "longitude": 105.71831730128878,
                       "latitude": 38.862000999988616
                   },
                   {
                       "longitude": 105.71831730128878,
                       "latitude": 38.862000999988616
                   },
                   {
                       "longitude": 105.71688860054067,
                       "latitude": 38.861934101065735
                   },
                   {
                       "longitude": 105.71499040140718,
                       "latitude": 38.86184090036685
                   },
                   {
                       "longitude": 105.71305559955356,
                       "latitude": 38.861745899027056
                   },
                   {
                       "longitude": 105.71124999867612,
                       "latitude": 38.861646400359639
                   },
                   {
                       "longitude": 105.70920529939372,
                       "latitude": 38.861542500174416
                   },
                   {
                       "longitude": 105.70679479917123,
                       "latitude": 38.861427498971885
                   },
                   {
                       "longitude": 105.70494780031804,
                       "latitude": 38.861331801013968
                   },
                   {
                       "longitude": 105.70371569962192,
                       "latitude": 38.861274400257926
                   },
                   {
                       "longitude": 105.70364770006523,
                       "latitude": 38.861277401631227
                   },
                   {
                       "longitude": 105.70349519940417,
                       "latitude": 38.861283899668322
                   },
                   {
                       "longitude": 105.70355250109272,
                       "latitude": 38.861400601826368
                   },
                   {
                       "longitude": 105.70366080072777,
                       "latitude": 38.861566801548086
                   },
                   {
                       "longitude": 105.70382639993041,
                       "latitude": 38.861744602164094
                   },
                   {
                       "longitude": 105.70404950050357,
                       "latitude": 38.86195470032736
                   },
                   {
                       "longitude": 105.70441409945229,
                       "latitude": 38.862223601378261
                   },
                   {
                       "longitude": 105.70643840010032,
                       "latitude": 38.863852900751546
                   },
                   {
                       "longitude": 105.7081552013782,
                       "latitude": 38.865215899976192
                   },
                   {
                       "longitude": 105.70993379874808,
                       "latitude": 38.866653000368593
                   },
                   {
                       "longitude": 105.71160860018752,
                       "latitude": 38.867989402009016
                   },
                   {
                       "longitude": 105.71308769889465,
                       "latitude": 38.869192898736678
                   },
                   {
                       "longitude": 105.71364829866181,
                       "latitude": 38.869637400331577
                   },
                   {
                       "longitude": 105.71364840098016,
                       "latitude": 38.869637500908667
                   },
                   {
                       "longitude": 105.71371699892107,
                       "latitude": 38.8696918981644
                   }
               ]},
              {"car_id": 3,
               "start_point": {
                   "longitude": 105.71892594481322,
                   "latitude": 38.854270759487839
               },
               "pass_points": [
                   {
                       "longitude": 105.71888429971857,
                       "latitude": 38.855208398083782
                   },
                   {
                       "longitude": 105.718804399254,
                       "latitude": 38.856252600646904
                   },
                   {
                       "longitude": 105.718804399254,
                       "latitude": 38.856252600646904
                   },
                   {
                       "longitude": 105.71873950109577,
                       "latitude": 38.857100998154841
                   },
                   {
                       "longitude": 105.7186005987614,
                       "latitude": 38.858820799709768
                   },
                   {
                       "longitude": 105.71845210114108,
                       "latitude": 38.860722401698133
                   },
                   {
                       "longitude": 105.71832589887211,
                       "latitude": 38.861902098710246
                   },
                   {
                       "longitude": 105.71831730128878,
                       "latitude": 38.862000999988616
                   },
                   {
                       "longitude": 105.71831730128878,
                       "latitude": 38.862000999988616
                   },
                   {
                       "longitude": 105.71831730128878,
                       "latitude": 38.862000999988616
                   },
                   {
                       "longitude": 105.71688860054067,
                       "latitude": 38.861934101065735
                   },
                   {
                       "longitude": 105.71499040140718,
                       "latitude": 38.86184090036685
                   },
                   {
                       "longitude": 105.71305559955356,
                       "latitude": 38.861745899027056
                   },
                   {
                       "longitude": 105.71124999867612,
                       "latitude": 38.861646400359639
                   },
                   {
                       "longitude": 105.70920529939372,
                       "latitude": 38.861542500174416
                   },
                   {
                       "longitude": 105.70679479917123,
                       "latitude": 38.861427498971885
                   },
                   {
                       "longitude": 105.70494780031804,
                       "latitude": 38.861331801013968
                   },
                   {
                       "longitude": 105.70371569962192,
                       "latitude": 38.861274400257926
                   },
                   {
                       "longitude": 105.70364770006523,
                       "latitude": 38.861277401631227
                   },
                   {
                       "longitude": 105.70349519940417,
                       "latitude": 38.861283899668322
                   },
                   {
                       "longitude": 105.70355250109272,
                       "latitude": 38.861400601826368
                   },
                   {
                       "longitude": 105.70366080072777,
                       "latitude": 38.861566801548086
                   },
                   {
                       "longitude": 105.70382639993041,
                       "latitude": 38.861744602164094
                   },
                   {
                       "longitude": 105.70404950050357,
                       "latitude": 38.86195470032736
                   },
                   {
                       "longitude": 105.70441409945229,
                       "latitude": 38.862223601378261
                   },
                   {
                       "longitude": 105.70643840010032,
                       "latitude": 38.863852900751546
                   },
                   {
                       "longitude": 105.7081552013782,
                       "latitude": 38.865215899976192
                   },
                   {
                       "longitude": 105.70993379874808,
                       "latitude": 38.866653000368593
                   },
                   {
                       "longitude": 105.71160860018752,
                       "latitude": 38.867989402009016
                   },
                   {
                       "longitude": 105.71308769889465,
                       "latitude": 38.869192898736678
                   },
                   {
                       "longitude": 105.71364829866181,
                       "latitude": 38.869637400331577
                   },
                   {
                       "longitude": 105.71364840098016,
                       "latitude": 38.869637500908667
                   },
                   {
                       "longitude": 105.71371699892107,
                       "latitude": 38.8696918981644
                   }
               ]}
              ]

data_dict = {'car_point_total': 3,
             "car_points": car_points,
             "operate_id": 2}


def read_client_path(round_id):
    path_name = "D:/session/session_2/subject_2/client_path_" + \
        str(round_id)+".json"
    with open(path_name, 'r') as load_f:
        load_dict = json.load(load_f)

    rescue_peoples = []
    people_id = []
    people_type = []
    for rescue_people in load_dict["rescue_people"]:
        # if((rescue_people["people_type"] >= filter_id)):
        rescue_peoples.append([rescue_people["people_point"]
                               ["longitude"], rescue_people["people_point"]["latitude"]])
        people_id.append(rescue_people["people_id"])

    return rescue_peoples, people_id


def read_client_path_new(round_id):
    path_name = "D:/session/session_2/subject_2/client_path_" + \
        str(round_id)+".json"

    with open(path_name, 'r') as load_f:
        load_dict = json.load(load_f)

    rescue_info = []
    for rescue_people in load_dict["rescue_people"]:
        # if((rescue_people["people_type"] >= filter_id)):
        rescue_peoples = [rescue_people["people_point"]
                          ["longitude"], rescue_people["people_point"]["latitude"]]
        rescue_info.append(
            (rescue_peoples, rescue_people["people_id"], rescue_people["people_type"]))

    return rescue_info


class MyKmeans:
    def __init__(self, k, data, do_shuffle=False):
        self.k = k
        self.data = data
        self.do_shuffle = do_shuffle

    # 计算欧氏距离
    def cal_dist(self, p1, p2):
        return np.sqrt(np.sum((p1-p2)**2))

    # 初始化聚类中心和每个样本所属类别
    def initialize(self):
        if self.do_shuffle:
            np.random.shuffle(self.data)
        # 初始化聚类中心
        self.centers = self.data[:self.k]
        # 初始化每个样本所属簇
        self.targets = np.zeros(self.data.shape[0])

    def one_step(self):
        for i, item in enumerate(self.data):  # 对于每一个样本点
            c = []  # 分别计算该样本点到k个聚类中心的距离，并存入c
            for j in range(len(self.centers)):
                c.append(self.cal_dist(item, self.centers[j]))
            # print(c)
            self.targets[i] = np.argmin(c)  # 更新targets

        # 更新聚类中心
        new_centers = []
        for i in range(self.k):  # 对于每一个类中的全部样本点
            # 此时target的取值集合是0到k-1

            # 挑选出属于簇i的全部样本
            i_data = []
            for index, item in enumerate(self.data):
                if self.targets[index] == i:
                    i_data.append(item)
            if len(i_data) != 0:
                cent = []  # 存储新的聚类中心的每一个维度
                for p in range(len(self.data[0])):  # 对于点的每一个维度
                    sums = 0

                    # 计算第i个簇中，每个维度的新值
                    for x in i_data:
                        sums += x[p]
                    res = sums/len(i_data)
                    cent.append(res)
                new_centers.append(cent)
            else:
                new_centers.append(self.centers[i])  # 若某一个簇中所含样本数为0，则不更新该簇的中心点
        self.centers = new_centers

    def run(self, iterations):
        self.initialize()  # 初始化聚类中心和各样本所属类别
        # 经过iterations次迭代，基本就完成了聚类
        for it in range(iterations):
            # print('iterations',it)
            self.one_step()
        return self.centers, self.targets

    def group(self, src, centers, delta):

        m = src.shape[0]
        label = np.zeros((m, 1))
        # print(src[0])
        for i, item in enumerate(src):  # 对于每一个样本点
            c = []  # 分别计算该样本点到k个聚类中心的距离，并存入c
            for j in range(len(centers)):
                c.append(self.cal_dist(item, centers[j]))

            label[i] = np.argmin(c)  # 更新targets
        return label


def random_int(length, a, b):
    # length为生成列表的长度,a是下边界,b是上边界
    list = []  # 首先生成定义一个空列表
    count = 0
    while (count < length):
        # 这里通过while跳出循环
        number = random.randint(a, b)
        number2 = random.randint(a, b)  # 生成一个随机数
        list.append([number, number2])  # 添加生成的随机数到list中
        count = count + 1  # 计数器,达到长度跳出循环
    return list


def eucliDist(A, B):
    return math.sqrt(sum([(a - b) ** 2 for (a, b) in zip(A, B)]))

    # for i in range(m):
    #     for j in range(m):
    #         if(fabs(src[i]-check_data[j]))

    # number = 1
    # for loopi in range(m):
    #     if(label[loopi] == 0):
    #         deltadata = data_new - data_new[loopi]
    #         dis = (deltadata * deltadata).sum(axis=1)
    #         label[dis < delta] = number
    #         number += 1

    return label


def out_data(round_id):
    # datasets=np.random.randint(0,100,size=(100,2))
    # for i in range(4):
    d1, pds = read_client_path(round_id)
    datasets = np.array(d1)
    src = np.array(d1)
    k = 3  # 聚类数
    iterations = 100  # 总迭代次数
    # print(datasets)
    mykmeans = MyKmeans(k, datasets, True)  # 实例化
    centers, targets = mykmeans.run(iterations)  # 迭代求解
    label = mykmeans.group(src, centers, 1e-6)
    # 可视化聚类结果
    # plt.figure(figsize=(10, 10), dpi=100)
    data2 = pd.DataFrame(d1, columns=['longitude', 'latitude'])
    label2 = pd.DataFrame(label, columns=['label'])
    people_id_pd = pd.DataFrame(pds, columns=['people_id'])
    data_set = pd.concat([data2, label2, people_id_pd], axis=1)
    # plt.scatter(src[:, 1], src[:, 0], c=label)

    d4 = (data_set[[each == 0.0 for each in data_set['label']]]
          ).sort_values(by="longitude")
    d3 = (data_set[[each == 2.0 for each in data_set['label']]]
          ).sort_values(by="longitude")
    d2 = (data_set[[each == 1.0 for each in data_set['label']]]
          ).sort_values(by="longitude")
    # print(d4)
    print(d4.shape, d3.shape, d2.shape)
    # print(data_set)
    # f.toJons((d2, d3, d4))
    # 绘制聚类中心
    # for center in centers:
    #     plt.scatter(center[1], center[0], marker='*', s=300)
    #     plt.text(center[1], center[0], (round(center[0], 2),
    #                                     round(center[1], 2)), fontsize=10, color="r")

    # plt.show()
    return (d2, d3, d4), centers


def random_int(length, a, b):
    # length为生成列表的长度,a是下边界,b是上边界
    list = []
# 首先生成定义一个空列表
    count = 0
    while (count < length):
        # 这里通过while跳出循环
        number = random.randint(a, b)
        number2 = random.randint(a, b)
# 生成一个随机数
        list.append([number, number2])
# 添加生成的随机数到list中
        count = count + 1
# 计数器,达到长度跳出循环
    return list


def GetDistance(p1, p2):
    lat1 = p1[1]
    long1 = p1[0]
    lat2 = p2[1]
    long2 = p2[0]
    if (lat1 == lat2) and long1 == long2:
        return -1
    val = np.sin(lat1 * 0.01745329) * np.sin(lat2 * 0.01745329) + np.cos(lat1 *
                                                                         0.01745329) * np.cos(lat2 * 0.01745329) * np.cos((long1 - long2) * 0.01745329)
    if(val > 1):
        # print(p1,p2)
        return -1
    return 6378137 * np.arccos(val)


def GetDistance222(p1, p2):
    lat1 = p1[1]
    long1 = p1[0]
    lat2 = p2[1]
    long2 = p2[0]
    # if (lat1==lat2) and long1==long2:
    #     return -1
    # val = np.sin(lat1 * 0.01745329) * np.sin(lat2 * 0.01745329) + np.cos(lat1 *
    #                                                                      0.01745329) * np.cos(lat2 * 0.01745329) * np.cos((long1 - long2) * 0.01745329)
    # if(val>1):
    #     # print(p1,p2)
    #     return -1
    return np.fabs(lat1-lat2)+np.fabs(long1-long2)


def eucliDist(A, B):
    return math.sqrt(sum([(a - b) ** 2 for (a, b) in zip(A, B)]))


def toJons(d1, name='D:/session/session_2/subject_2/team_path_1.json', round_id=1):

    for i in range(3):
        car_points[i]["car_id"] = i+1
        car_points[i]["start_point"]['latitude'] = d1[i]['latitude'].values[0]
        car_points[i]["start_point"]['longitude'] = d1[i]['longitude'].values[0]
        car_points[i]["pass_points"] = []
        for index in range(0, len(d1[i]['longitude'].values)):
            car_points[i]["pass_points"].append({
                "longitude": d1[i]['longitude'].values[index],
                "latitude": d1[i]['latitude'].values[index]
            })
    data_dict["operate_id"] = round_id
    with open(name, 'w', encoding='utf-8') as f:
        f.write(json.dumps(data_dict, ensure_ascii=False))


def toJonsPeolpes(d1):
    f = open('./data/gen_people_75id.csv', 'w', encoding='utf-8', newline='')
    csv_writer = csv.writer(f)
    for i in range(3):
        val = d1[i]['people_id'].values.astype("int")
        # print(val[0])
        csv_writer.writerow(val)
    f.close()


def view_maps(view):
    points = []
    with open("D:/session/map/RoadLine.json", 'rb') as load_f:
        RoadLine = json.load(load_f)
    for rd in RoadLine:  # len(RoadLine)):
        dt = rd["geometry"]["coordinates"]
        if dt == []:
            continue
        points += dt
        if view:
            DTS = np.array(dt)
            plt.plot(DTS[:, 1], DTS[:, 0], color=colors[1], linewidth=0.50)

    with open("D:/session/map/RoadPoint.json", 'rb') as load_f:
        RoadPoint = json.load(load_f)

    for rd in RoadPoint:  # len(RoadLine)):
        dt = rd["geometry"]["coordinates"]
        if dt == []:
            continue
        if view:
            dtarray = np.array(dt)
            plt.scatter(dtarray[1], dtarray[0],
                        color=colors[0], edgecolors='none', s=10, linewidth=0.50)
    return points
